let Consts = {
	OpenDataKeys: {
		ScoreKey: "score", // json.string
	},
	DomainAction: {
		FetchFriendScore: "total_rank", //好友关卡得分排行
		HorConmpar: "near_rank", //横向比较 horizontal comparison
		Scrolling: "scrolling"
	},
}

const PAGE_SIZE = 4;
const ITEM_WIDTH = 590;
const ITEM_HEIGHT = 120;

const RANK_PAGE_HEIGHT = ITEM_HEIGHT * PAGE_SIZE;

const dataSorter = (gameDatas, field = Consts.OpenDataKeys.ScoreKey) => {
	let data = []
	for (let i = 0; i < gameDatas.length; i++) {
		if (gameDatas[i].KVDataList[0]) {
			data.push(gameDatas[i])
		}
	}

	let newData = data.sort((a, b) => {
		let va = a.KVDataList[0] ? a.KVDataList[0].value - 0 : 0
		let vb = b.KVDataList[0] ? b.KVDataList[0].value - 0 : 0
		return vb - va;
	});
	
	return newData
}

class RankListRenderer {
	constructor() {
		this.clearFlag = false
		this.offsetY = 0;
		this.maxOffsetY = 0;
		this.gameDatas = [];    //https://developers.weixin.qq.com/minigame/dev/document/open-api/data/UserGameData.html
		
		
		this.curPageIndex = 0; //当前页码
		this.drawIconCount = 0;
		this.rankCanvasList = [];

		//用于用户头像、我的排名 图片只刷新一次，防止闪屏       
        this.initImage = false;		//我的头像
        this.initRankImage = false; //我的排名分隔符
        this.initRankScoreImage = false; //我的排名名次
        this.initSelfFlag = false;		//我的排名全部显示

		this.selfUserInfo = null //avatarUrl //https://developers.weixin.qq.com/minigame/dev/document/open-api/data/wx.getUserInfo.html
		this.selfUserScore = null;
		this.selfRank = 1;
		this.init();
	}

	init() {
		this.sharedCanvas = wx.getSharedCanvas();
		this.sharedCtx = this.sharedCanvas.getContext('2d');
		console.log('init class')
		this.fetchSelfInfo();

	}


	listen() {
		//msg -> {type, value}
		wx.onMessage(msg => {
			console.log("ranklist wx.onMessage", msg);
			switch (msg.type) {
				case Consts.DomainAction.HorConmpar:
					console.log(Consts.DomainAction.HorConmpar);
					this.clearFlag = true
					this.fetchHorFriendScoreData(msg.value)
					// this.horizontalComparison()
					break;				
				case Consts.DomainAction.FetchFriendScore:
					console.log(Consts.DomainAction.FetchFriendScore);
					this.clearFlag = true;
					this.initSelfFlag = false;
					this.fetchFriendScoreData();
					break;
				case Consts.DomainAction.Scrolling:
					this.clearFlag = false
					if (!this.gameDatas.length) {
						return;
					}
					const deltaY = msg.value;
					const newOffsetY = this.offsetY + deltaY;
					if (newOffsetY < 0) {
						//   console.log("前面没有更多了");
						return;
					}
					if (newOffsetY + PAGE_SIZE * ITEM_HEIGHT > this.maxOffsetY) {
						//   console.log("后面没有更多了");
						return;
					}
					this.offsetY = newOffsetY;
					this.showRanks(newOffsetY);
					break;

				default:
					console.log(`未知消息类型:msg.type=${msg.type}`);
					break;
			}
		});
	}

	fetchSelfInfo() {
		wx.getUserInfo({
			openIdList: ["selfOpenId"],
			success: res => {
				console.log("fetchSelfCloudData success res=>", res)
				this.selfUserInfo = res.data[0];
				wx.getUserCloudStorage({
					keyList:[Consts.OpenDataKeys.ScoreKey],
					success: res => {
						console.log("wx.getUserCloudStorage success", res);
						if(!res.KVDataList[0]){
							wx.setUserCloudStorage({
								KVDataList:[{key:Consts.OpenDataKeys.ScoreKey, value:"1"}],
								success: res => {
									console.log("wx.setUserCloudStorage success", res);
									wx.getFriendCloudStorage({
										keyList: [
											Consts.OpenDataKeys.ScoreKey,
										],
										success: res => {
											console.log("wx.fetchHorFriendScoreData success", res);
											this.gameDatas = dataSorter(res.data, Consts.OpenDataKeys.ScoreKey);
											for (let i = 0; i < this.gameDatas.length; i++) {
												if ( this.gameDatas[i].avatarUrl === this.selfUserInfo.avatarUrl) {
													this.selfUserScore = this.gameDatas[i];	
													this.selfRank = i + 1;												
													break;
												}
											}
											
											this.horizontalComparison()
										},
										fail: res => {
											console.log("wx.fetchHorFriendScoreData fail", res);
										},
									});
								},
								fail: res => {
									console.log("wx.setUserCloudStorage fail", res);
								},
							})
						}
						else
						{
							wx.getFriendCloudStorage({
								keyList: [
									Consts.OpenDataKeys.ScoreKey,
								],
								success: res => {
									console.log("wx.fetchHorFriendScoreData success", res);
									this.gameDatas = dataSorter(res.data, Consts.OpenDataKeys.ScoreKey);
									for (let i = 0; i < this.gameDatas.length; i++) {
										if ( this.gameDatas[i].avatarUrl === this.selfUserInfo.avatarUrl) {
											this.selfUserScore = this.gameDatas[i];	
											this.selfRank = i + 1;										
											break;
										}
									}
									
									this.horizontalComparison()
								},
								fail: res => {
									console.log("wx.fetchHorFriendScoreData fail", res);
								},
							});
						}
					},
					fail: res => {
						console.log("wx.getUserCloudStorage fail", res);
					},
				})
				
			}
		})
	}	

	//取出所有好友数据 关卡得分
	fetchFriendScoreData() {
		wx.getFriendCloudStorage({
			keyList: [
				Consts.OpenDataKeys.ScoreKey,
			],
			success: res => {
				console.log("wx.getFriendCloudStorage success", res);				
				this.gameDatas = dataSorter(res.data, Consts.OpenDataKeys.ScoreKey);
				const dataLen = this.gameDatas.length;
				this.offsetY = 0;
				this.maxOffsetY = dataLen * ITEM_HEIGHT;
				if (dataLen) {
					this.showRanks(0);
				}
			},
			fail: res => {
				console.log("wx.getFriendCloudStorage fail", res);
			},
		});
	}

	// 横向比较关卡得分
	fetchHorFriendScoreData(selfScore) {
		wx.getFriendCloudStorage({
			keyList: [
				Consts.OpenDataKeys.ScoreKey,
			],
			success: res => {
				console.log("wx.fetchHorFriendScoreData success", res);
				
				for (let i = 0; i < res.data.length; i++) {
					if ( res.data[i].avatarUrl === this.selfUserInfo.avatarUrl) {
						if(res.data[i].KVDataList[0].value < selfScore){
							res.data[i].KVDataList[0].value = selfScore
						}
						break;
					}
				}
				this.gameDatas = dataSorter(res.data, Consts.OpenDataKeys.ScoreKey);
				this.horizontalComparison()
			},
			fail: res => {
				console.log("wx.fetchHorFriendScoreData fail", res);
			},
		});
	}

	initSelf(data, rank,ctx,itemGapY) {//自己的
        const nick = data.nickname.length <= 6 ? data.nickname : data.nickname.substr(0, 4) + "...";
		const kvData = data.KVDataList[0];
		const grade = kvData ? kvData.value : 0;

		//背景颜色
		if (rank % 2 == 1) {
			ctx.fillStyle = "#c0d0d8";
			ctx.fillRect(0, itemGapY + 50, ITEM_WIDTH, ITEM_HEIGHT);
		}

		//显示我的排名
		const myrankImg = wx.createImage();
		let promise = this._setPromise(myrankImg, "cmd_rank/res/myRankImage.png");
		Promise.all([promise]).then(() => {
			ctx.drawImage(myrankImg, 0,itemGapY, 590, 50);

			//名次 这里可以设置前几名的名次背景
			if (rank <= 3) {
				const rankImg = wx.createImage();
				rankImg.src = `cmd_rank/res/ranking_no${rank}.png`;
	            rankImg.onload = () => {            		
					ctx.drawImage(rankImg, 10, 25 + itemGapY + 50, 78, 82);					
				};	        		
			} else {
				ctx.fillStyle = "#BDBDBD";
				ctx.textAlign = "right";
				ctx.baseLine = "middle";
				ctx.font = "40px Helvetica";
				ctx.fillText(`${rank}`, 60, 80 + itemGapY + 50);
			}

			//头像
			const avatarX = 120;
			const avatarY = 25 + itemGapY + 50;
			const avatarW = 80;
			const avatarH = 80;

			//我的头像函数
			//ctx.fillStyle = "#ffffff";
	        //ctx.fillRect(avatarX - 5, avatarY - 5, avatarW + 10, avatarH + 10);
	        const userImg = wx.createImage();
			userImg.src = data.avatarUrl;
	        
	        if(this.initImage == false){
	            //this.initImage = true;
	            userImg.onload = () => {
	                ctx.drawImage(userImg,avatarX,avatarY,avatarW,avatarH);
	            };
	        }
	        else{
	            ctx.drawImage(userImg,avatarX,avatarY,avatarW,avatarH);
	        }			

			//名字
			ctx.fillStyle = "#777063";
			ctx.textAlign = "left";
			ctx.baseLine = "middle";
			ctx.font = "30px Helvetica";
			ctx.fillText(nick, 220, 80 + itemGapY + 50);

			//分数
			ctx.fillStyle = "#777063";
			ctx.textAlign = "left";
			ctx.baseLine = "middle";
			ctx.font = "30px Helvetica";
			
			ctx.fillText(`${grade}`, 450, 80 + itemGapY + 50);
		})
    }

    _setPromise(img, src) {
        return new Promise((resolve, reject) => {
            img.src = src;
            if (!src) {
                resolve()
            }
            img.onload = () => {
                resolve();
            }
        }).then(() => {
            console.log('背景图加载完毕');
        }).catch((err) => {
            console.log('背景图加载失败：', err);
        });

    }

	// 根据滑动偏移绘制排行榜画布
	showRanks(offsetY) {
		this.curOffsetY = offsetY
		const sharedWidth = this.sharedCanvas.width;
		const sharedHeight = this.sharedCanvas.height;
		this.sharedCtx.clearRect(0, 0, sharedWidth, sharedHeight - 170);
		if (this.clearFlag){
			this.clearFlag = false
			this.rankCanvasList = [];			
		}

		const pageY = offsetY % RANK_PAGE_HEIGHT;
		const pageIndex = Math.floor(offsetY / RANK_PAGE_HEIGHT);		
		const isOverOnePage = pageY + sharedHeight -170> RANK_PAGE_HEIGHT;

		let rankCanvas = this.getCanvasByPageIndex(pageIndex);
		if (!isOverOnePage) {
			console.log("isOverOnePage:",isOverOnePage,sharedHeight)
			this.sharedCtx.drawImage(rankCanvas, 0, pageY, sharedWidth, sharedHeight);
			
			
		} else {
			console.log("isOverOnePage:",isOverOnePage)
			//绘制当前页后半部分
			const partialHeight = RANK_PAGE_HEIGHT - pageY;
			
			this.sharedCtx.drawImage(rankCanvas, 0, pageY, sharedWidth, partialHeight,0, 0, sharedWidth, partialHeight);
			//绘制下一页前半部分
			rankCanvas = this.getCanvasByPageIndex(pageIndex + 1);
			this.sharedCtx.drawImage(rankCanvas, 0, 0, sharedWidth, sharedHeight - partialHeight-ITEM_HEIGHT -50,0, partialHeight, sharedWidth, sharedHeight - partialHeight-160);
			//this.sharedCtx.drawImage(this.selfUserScore, 0, 0, sharedWidth, sharedHeight - partialHeight-ITEM_HEIGHT -50,0, partialHeight, sharedWidth, sharedHeight - partialHeight-160);
		}
		if(this.initSelfFlag == false)
		{
			this.initSelfFlag = true;
			this.initSelf(this.selfUserScore,this.selfRank,this.sharedCtx,ITEM_HEIGHT *4);
		}
		
		//this.initSelf(this.selfUserScore,this.selfRank,this.sharedCtx,ITEM_HEIGHT *4);
	}

	_drawRankItem(ctx, index, rank, data, pageLen) {
		const nick = data.nickname.length <= 6 ? data.nickname : data.nickname.substr(0, 4) + "...";
		const kvData = data.KVDataList[0];
		const grade = kvData ? kvData.value : 0;

		//背景颜色
		if (rank % 2 == 1) {
			ctx.fillStyle = "#FFD700";
			ctx.fillRect(0, itemGapY, ITEM_WIDTH, ITEM_HEIGHT);
		}
		else
		{
			ctx.fillStyle = "#FFC0CB";
			ctx.fillRect(0, itemGapY, ITEM_WIDTH, ITEM_HEIGHT);
		}

		//名次 这里可以设置前几名的名次背景
		if (rank <= 3) {
			const rankImg = wx.createImage();
			rankImg.src = `cmd_rank/res/ranking_no${rank}.png`;
			rankImg.onload = () => {
				// if (prevOffsetY == this.offsetY) {
				ctx.drawImage(rankImg, 10, 25 + itemGapY, 78, 82);
				// }
			};
		} else {
			ctx.fillStyle = "#BDBDBD";
			ctx.textAlign = "right";
			ctx.baseLine = "middle";
			ctx.font = "40px Helvetica";
			ctx.fillText(`${rank}`, 60, 80 + itemGapY);
		}

		//头像
		const avatarX = 120;
		const avatarY = 25 + itemGapY;
		const avatarW = 80;
		const avatarH = 80;
		this.drawAvatar(ctx, data, avatarX, avatarY, avatarW, avatarH, (avatarImg) => {
			// if (prevOffsetY == this.offsetY) {
			ctx.drawImage(avatarImg, avatarX, avatarY, avatarW, avatarH);
			// }
			
			if(this.drawIconCount>=this.gameDatas.length-1 || this.drawIconCount >=PAGE_SIZE-1){
				this.drawIconCount = 0;
				this.showRanks(this.curOffsetY)
			}else{
				this.drawIconCount++;
			}
		})

		//名字
		ctx.fillStyle = "#777063";
		ctx.textAlign = "left";
		ctx.baseLine = "middle";
		ctx.font = "30px Helvetica";
		ctx.fillText(nick, 220, 80 + itemGapY);

		//分数
		ctx.fillStyle = "#777063";
		ctx.textAlign = "left";
		ctx.baseLine = "middle";
		ctx.font = "30px Helvetica";
		
		ctx.fillText(`${grade}`, 450, 80 + itemGapY);
	}

	
	// 获取指定页码的排行榜
	getCanvasByPageIndex(pageIndex){
		let canvas = this.rankCanvasList[pageIndex];
		if (!canvas) {
			canvas = wx.createCanvas();
			canvas.width = this.sharedCanvas.width;
			canvas.height = RANK_PAGE_HEIGHT + 50 +ITEM_HEIGHT;
			this.rankCanvasList[pageIndex] = canvas;
			const ctx = canvas.getContext('2d');
			this.drawPagedRanks(ctx, pageIndex);
		}
		return canvas;
	}

	drawPagedRanks(ctx, pageIndex) {
		for (let i = 0; i < PAGE_SIZE; i++) {
			const pageOffset = pageIndex * PAGE_SIZE;
			const data = this.gameDatas[pageOffset + i];
			if (!data) continue;
			console.log("this.selfUserScore:",this.selfUserScore);
			console.log("this.selfUserInfo data:",data);
			this.drawRankItemEx(ctx, pageOffset+i+1, data, ITEM_HEIGHT * i)
		}
	}

	drawAvatar(ctx, data, x, y, w, h, cb) {
		// avatarUrl = avatarUrl.substr(0, avatarUrl.lastIndexOf('/')) + "/132";
		ctx.fillStyle = "#ffffff";
		ctx.fillRect(x - 5, y - 5, w + 10, h + 10);

		const avatarImg = wx.createImage();
		avatarImg.src = data.avatarUrl;
		avatarImg.onload = () => {
			cb(avatarImg);
		};
	}

	drawAvatar1(ctx, data, x, y, w, h, cb) {
        // avatarUrl = avatarUrl.substr(0, avatarUrl.lastIndexOf('/')) + "/132";
        ctx.fillStyle = "#ffffff";
        ctx.fillRect(x - 5, y - 5, w + 10, h + 10);
        const avatarImg = wx.createImage();
		avatarImg.src = data.avatarUrl;
        
        if(this.initImage == false){
            this.initImage = true;
            avatarImg.onload = () => {
                cb(avatarImg);
            };
        }
        else{
            cb(avatarImg);
        }
    }

	drawRankItemEx(ctx, rank, data, itemGapY) {
		const nick = data.nickname.length <= 6 ? data.nickname : data.nickname.substr(0, 4) + "...";
		const kvData = data.KVDataList[0];
		const grade = kvData ? kvData.value : 0;

		//背景颜色
		if (rank % 2 == 1) {
			ctx.fillStyle = "#FFD700";
			ctx.fillRect(0, itemGapY, ITEM_WIDTH, ITEM_HEIGHT);
		}
		else
		{
			ctx.fillStyle = "#FFC0CB";
			ctx.fillRect(0, itemGapY, ITEM_WIDTH, ITEM_HEIGHT);
		}

		//名次 这里可以设置前几名的名次背景
		if (rank <= 3) {
			const rankImg = wx.createImage();
			rankImg.src = `cmd_rank/res/ranking_no${rank}.png`;
			rankImg.onload = () => {
				// if (prevOffsetY == this.offsetY) {
				ctx.drawImage(rankImg, 10, 25 + itemGapY, 78, 82);
				// }
			};
		} else {
			ctx.fillStyle = "#BDBDBD";
			ctx.textAlign = "right";
			ctx.baseLine = "middle";
			ctx.font = "40px Helvetica";
			ctx.fillText(`${rank}`, 60, 80 + itemGapY);
		}

		//头像
		const avatarX = 120;
		const avatarY = 25 + itemGapY;
		const avatarW = 80;
		const avatarH = 80;
		this.drawAvatar(ctx, data, avatarX, avatarY, avatarW, avatarH, (avatarImg) => {
			// if (prevOffsetY == this.offsetY) {
			ctx.drawImage(avatarImg, avatarX, avatarY, avatarW, avatarH);
			// }
			
			if(this.drawIconCount>=this.gameDatas.length-1 || this.drawIconCount >=PAGE_SIZE-1){
				this.drawIconCount = 0;
				this.showRanks(this.curOffsetY)
			}else{
				this.drawIconCount++;
			}
		})

		//名字
		ctx.fillStyle = "#777063";
		ctx.textAlign = "left";
		ctx.baseLine = "middle";
		ctx.font = "30px Helvetica";
		ctx.fillText(nick, 220, 80 + itemGapY);

		//分数
		ctx.fillStyle = "#777063";
		ctx.textAlign = "left";
		ctx.baseLine = "middle";
		ctx.font = "30px Helvetica";
		
		ctx.fillText(`${grade}`, 450, 80 + itemGapY);
		
	}

	drawRankItemHor(ctx, rank, data, itemPos) {
		if (!data) return;
		let width = this.sharedCanvas.width
		const nick = data.nickname.length <= 6 ? data.nickname : data.nickname.substr(0, 10) + "...";
		const kvData = data.KVDataList[0];
		const grade = kvData ? kvData.value : 0;

		let avatarX
		if (itemPos === 1) {
			avatarX = width / 6
		} else if (itemPos === 2) {
			avatarX = width * 0.5
		} else if (itemPos === 3) {
			avatarX = width * 5 / 6
		}

		//名次
		if (itemPos === 2) {
			ctx.fillStyle = "#00ff00";
		} else {
			ctx.fillStyle = "#ffffff";
		}
		ctx.textAlign = "center";
		ctx.baseLine = "middle";
		ctx.font = "40px Helvetica";
		ctx.fillText(rank, avatarX, 130);

		//名字
		if (itemPos === 2) {
			ctx.fillStyle = "#00ff00";
		} else {
			ctx.fillStyle = "#ffffff";
		}
		ctx.textAlign = "center";
		ctx.baseLine = "middle";
		ctx.font = "30px Helvetica";
		ctx.fillText(nick, avatarX, 300);

		//分数
		if (itemPos === 2) {
			ctx.fillStyle = "#00ff00";
		} else {
			ctx.fillStyle = "#ffffff";
		}
		ctx.textAlign = "center";
		ctx.baseLine = "middle";
		ctx.font = "30px Helvetica";
		ctx.fillText(grade, avatarX, 350);

		//头像
		const avatarY = 160;
		const avatarW = 80;
		const avatarH = 80;
		this.drawAvatar(ctx, data, avatarX - 40, avatarY, avatarW, avatarH, (avatarImg) => {
			
			// if (prevOffsetY == this.offsetY) {
			ctx.drawImage(avatarImg, avatarX - 40, avatarY, avatarW, avatarH);
			// }
		})

	}

	horizontalComparison() {
		let height = this.sharedCanvas.height
		let width = this.sharedCanvas.width
		let border = 3
		let padding = 15
		// setInterval(dt=>{
		this.sharedCtx.clearRect(0, 0, 1000, 1000);
		this.sharedCtx.fillStyle = "#262833";
		this.sharedCtx.fillRect(0, 0, width, height);

		this.sharedCtx.fillStyle = "#373a4a";
		this.sharedCtx.fillRect(padding, padding, border, height - padding * 2);
		this.sharedCtx.fillRect(width - padding, padding, border, height - padding * 2);
		// this.sharedCtx.fillRect(width * 0.333, padding + 60, border, height - padding * 2 - 60);
		// this.sharedCtx.fillRect(width * 0.666, padding + 60, border, height - padding * 2 - 60);

		this.sharedCtx.fillRect(padding, padding, width - padding * 2, border);
		this.sharedCtx.fillRect(padding, padding + 60, width - padding * 2, border);
		this.sharedCtx.fillRect(padding, height - padding, width - padding * 2, border);

		this.sharedCtx.fillStyle = "#181a22";
		this.sharedCtx.fillRect(width * 0.333, padding + border + 60, width * 0.333+border, (height - padding * 2 - 60-border));

		this.sharedCtx.fillStyle = "#ffffff"
		this.sharedCtx.textAlign = "left";
		this.sharedCtx.baseLine = "middle";
		this.sharedCtx.font = "30px Helvetica";
		this.sharedCtx.fillText(`排行`, padding + 20, 60);

		let d1, d2, d3, selfRank
		for (let i = 0; i < this.gameDatas.length; i++) {
			if (this.gameDatas[i].avatarUrl === this.selfUserInfo.avatarUrl) {
				selfRank = i
				d1 = this.gameDatas[i - 1]
				d2 = this.gameDatas[i]
				d3 = this.gameDatas[i + 1]
				break;
			}
		}

		this.drawRankItemHor(this.sharedCtx, selfRank, d1, 1)
		this.drawRankItemHor(this.sharedCtx, selfRank + 1, d2, 2)
		this.drawRankItemHor(this.sharedCtx, selfRank + 2, d3, 3)

		// },100)

	}

}

const rankList = new RankListRenderer();
rankList.listen();
